package com.ld.caodan.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.UUID;

import android.util.Log;

/**
 * 
 * 模拟单一线程的 HTTP POST 方法提交表单， 使用 multipart/form-data 编码上传单一文件
 * 
 * @author 刘笛 Dec 14, 2010 4:08:36 PM
 */
public class FilePoster {
    private URL httpUrl = null; // 接收文件的地址，比如：http://server/save.jsp
    private File localFile = null; // 待上传的文件地址，比如：c:\\upload\\test.txt
    // 模拟 multipart/form-data 编码的 boundary
    String theBoundary = MakeBoundary();

    /**
     * 构造函数
     * 
     * @param postUrl
     *            请求的url
     * @param filePath
     *            上传文件路径
     */
    public FilePoster(String postUrl, String filePath) {
	try {
	    httpUrl = new URL(postUrl);
	    localFile = new File(filePath);
	} catch (MalformedURLException e) {
	    Log.e("FilePoster", "不规则的Url请求");
	}
    }

    /**
     * 构造函数
     * 
     * @param postUrl
     *            请求的url
     * @param file
     *            要上传的文件
     */
    public FilePoster(String postUrl, File file) {
	try {
	    httpUrl = new URL(postUrl);
	    localFile = file;
	} catch (MalformedURLException e) {
	    Log.e("FilePoster", "不规则的Url请求");
	}
    }

    public String doPost() {
	HttpURLConnection httpConnection = null;
	OutputStream outputStream = null;
	InputStream inputStream = null;
	try {
	    // 打开连接
	    httpConnection = (HttpURLConnection) httpUrl.openConnection();
	    httpConnection.setDoOutput(true);
	    // 设置接收类型：任意类型，UTF-8编码
	    httpConnection
		    .setRequestProperty("Accept", "*/*,charset=\"utf-8\"");
	    // 设置连接类型：自动关闭
	    httpConnection.setRequestProperty("Connection", "close");
	    UploadFile(httpConnection);
	    // 读取返回字符串
	    inputStream = httpConnection.getInputStream();
	    int length = httpConnection.getContentLength();
	    String str = readUTF8String(inputStream, length);
	    // 在操作完成之后断开连接
	    httpConnection.disconnect();
	    httpConnection = null;
	    // 关闭输入流
	    inputStream.close();
	    inputStream = null;
	    return str;
	} catch (Exception x) {
	    x.printStackTrace();
	} finally {
	    if (httpConnection != null)
		httpConnection.disconnect();
	    if (outputStream != null) {
		try {
		    outputStream.close();
		} catch (Exception x) {
		}
	    }
	    if (inputStream != null) {
		try {
		    inputStream.close();
		} catch (Exception x) {
		}
	    }
	}

	return null;
    }

    String MakeBoundary() {
	String str = UUID.randomUUID().toString();
	int len = 27 + 32;
	char[] buf = new char[len];
	int i;
	for (i = 0; i < 27; i++)
	    buf[i] = '-';
	for (int j = 0, n = str.length(); j < n && i < len; j++) {
	    char ch = str.charAt(j);
	    if (ch != '-') {
		buf[i++] = ch;
	    }
	} // for
	str = new String(buf);
	return str;
    }

    void UploadFile(HttpURLConnection connection)
	    throws UnsupportedEncodingException, IOException {
	OutputStream stream = null;
	FileInputStream fileStream = null;
	try {
	    String str = String
		    .format(
			    "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: %s\r\n\r\n",
			    theBoundary, // boundary
			    "file", // 表单中，文件元素的名称
			    localFile.getAbsolutePath(), // 上传文件的位置信息
			    "application/octet-stream"); // 上传文件的MIME
	    byte[] head = str.getBytes("utf-8");

	    str = String.format("\r\n--%s--\r\n", theBoundary);
	    byte[] tail = str.getBytes("utf-8");

	    fileStream = new FileInputStream(localFile);
	    int len = fileStream.available();
	    len += head.length;
	    len += tail.length;

	    // 设置数据提交方式：POST
	    connection.setRequestMethod("POST");
	    // 设置数据类型（即：表单内容编码类型）
	    connection.setRequestProperty("Content-Type",
		    "multipart/form-data; boundary=" + theBoundary);
	    // 设置数据长度
	    connection.setFixedLengthStreamingMode(len);
	    // 获取输出流对象，输出数据内容
	    stream = connection.getOutputStream();
	    stream.write(head);
	    CopyStream(fileStream, stream);
	    stream.write(tail);
	} finally {
	    if (fileStream != null)
		fileStream.close();
	    if (stream != null)
		stream.close();
	}
    }

    String readUTF8String(InputStream stream, int length)
	    throws UnsupportedEncodingException, IOException {
	byte[] dat = new byte[length];
	stream.read(dat);
	String str = new String(dat, "utf-8");
	return str;
    }

    void CopyStream(InputStream input, OutputStream output) throws IOException {
	int bufSize = 4096;
	byte[] buf = new byte[bufSize];
	int len = input.read(buf);
	while (len > 0) {
	    output.write(buf, 0, len);
	    len = input.read(buf);
	} // while
    }

    // public static String post(String actionUrl, Map<String, String> params,
    // File file) {
    // try {
    // //数据分隔线
    // String BOUNDARY = "———7d4a6d158c9";
    // String MULTIPART_FORM_DATA = "multipart/form-data";
    //
    // URL url = new URL(actionUrl);
    // HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    // conn.setDoInput(true);//允许输入
    // conn.setDoOutput(true);//允许输出
    // conn.setUseCaches(false);//不使用Cache
    // conn.setRequestMethod("POST");
    // conn.setRequestProperty("Connection", "Keep-Alive");
    // conn.setRequestProperty("Charset", "UTF-8");
    // conn.setRequestProperty("Content-Type", MULTIPART_FORM_DATA +
    // "; boundary=" + BOUNDARY);
    // StringBuilder sb = new StringBuilder();
    // //上传的表单参数部分，格式请参考文章
    // for (Map.Entry<String, String> entry : params.entrySet()) {//构建表单字段内容
    // sb.append("–");
    // sb.append(BOUNDARY);
    // sb.append("\r\n");
    // sb.append("Content-Disposition: form-data; name=\""+ entry.getKey() +
    // "\"\r\n\r\n");
    // sb.append(entry.getValue());
    // sb.append("\r\n");
    // }
    // DataOutputStream outStream = new
    // DataOutputStream(conn.getOutputStream());
    // outStream.write(sb.toString().getBytes());//发送表单字段数据
    //
    // //上传的文件部分，格式请参考文章
    // for(FormFile file : files){
    // StringBuilder split = new StringBuilder();
    // split.append("–");
    // split.append(BOUNDARY);
    // split.append("\r\n");
    // split.append("Content-Disposition: form-data;name=\""+
    // file.getFormname()+"\";filename=\""+ file.getFilname() + "\"\r\n");
    // split.append("Content-Type: "+ file.getContentType()+"\r\n\r\n");
    // outStream.write(split.toString().getBytes());
    // outStream.write(file.getData(), 0, file.getData().length);
    // outStream.write("\r\n".getBytes());
    // }
    // byte[] end_data = ("–" + BOUNDARY + "–\r\n").getBytes();//数据结束标志
    // outStream.write(end_data);
    // outStream.flush();
    // int cah = conn.getResponseCode();
    // if (cah != 200) throw new RuntimeException("请求url失败");
    // InputStream is = conn.getInputStream();
    // int ch;
    // StringBuilder b = new StringBuilder();
    // while( (ch = is.read()) != -1 ){
    // b.append((char)ch);
    // }
    // outStream.close();
    // conn.disconnect();
    // return b.toString();
    // } catch (Exception e) {
    // throw new RuntimeException(e);
    // }
    // }

}
